package com.aoip.telemetry.telemetry.receive.handler;

import com.aoip.telemetry.telemetry.core.redis.RedisCache;
import com.aoip.telemetry.telemetry.entity.constant.TelemetryConstants;
import com.aoip.telemetry.telemetry.entity.enums.AbnoTypeEnum;
import com.aoip.telemetry.telemetry.entity.enums.CacheKeyEnum;
import com.aoip.telemetry.telemetry.entity.equipment.StOnlineStatusEntity;
import com.aoip.telemetry.telemetry.receive.session.Session;
import com.aoip.telemetry.telemetry.receive.session.SessionFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * 正常关闭连接和异常掉线
 * @author chenbai
 * @version 1.0
 * @date 2021/6/15 14:21
 */
@Component
@ChannelHandler.Sharable
public class QuitHandler extends ChannelInboundHandlerAdapter {

    @Resource
    private RedisCache redisCache;

    private static QuitHandler quitHandler;

    @PostConstruct
    public void init() {
        quitHandler = this;
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        stOffline(ctx.channel());
        super.channelInactive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        stOffline(ctx.channel());
        super.exceptionCaught(ctx, cause);
    }

    /**
     * 记录测站下线时间，更新下线状态
     *
     * @param channel 通讯通道
     * @author chenbai
     * @date 2022/2/21
     **/
    private void stOffline(Channel channel) {
        Session session = SessionFactory.getSession();
        if (session == null) {
            return;
        }
        String stCode = (String) session.getAttribute(channel, "stCode");
        String key = CacheKeyEnum.STATION_ONLINE_STATUS + ":" + stCode;
        StOnlineStatusEntity entity = quitHandler.redisCache.getCacheObject(key);
        entity.setOnlineStatus(TelemetryConstants.OFFLINE);
        entity.setOfflineTime(LocalDateTime.now());
        //   站点下线
        //   1、将redis中站点实时在线信息删除；
        //   2、将站点下线信息保存到redis历史上下线信息中，后续通过定时任务进行入库处理，同时未防止未开启定时任务或无对应定时任务，设置有效时间为5天
        long millis = System.currentTimeMillis();
        quitHandler.redisCache.deleteObject(key);
        quitHandler.redisCache.setCacheObject(CacheKeyEnum.STATION_ONLINE_STATUS_HIS + ":" + stCode + ":" + millis,
                entity, 5, TimeUnit.DAYS);
        redisCache.deleteObject(CacheKeyEnum.ST_GP_ABNO_INFO + ":" + AbnoTypeEnum.OFF_LINE + ":" + stCode);
        redisCache.setCacheObject(CacheKeyEnum.ST_GP_ABNO_INFO + ":" + AbnoTypeEnum.OFF_LINE + ":" + stCode, LocalDateTime.now());
        session.unbind(channel);
    }
}
